/*
 * kdtree_build.h
 *
 *  Created on: Apr 26, 2011
 *      Author: tqlong
 */

#include <fstream>
#include <cassert>
#include <limits>
#include <algorithm>
#include <queue>
#include <QtGui/QPen>
#include "geometric_problem.h"
#include "Log.h"
#include "kdtree.h"

void KDTreeBuild::loadData(const std::vector<std::string>& fName, bool binary)
{
  if (m_tree) { delete m_tree; m_tree = NULL; }
  if (fName.size() < n_data()) {
    Log::m_log << "Please provide at least " << n_data() << " file names" << endl;
    return;
  }
  common::loadVVec(fName[0], m_point, binary);
}

void KDTreeBuild::solve()
{
  int n = m_point.size();
  if (m_tree) { delete m_tree; m_tree = NULL; }
  if (m_set) { delete m_set; m_set = NULL; }
  m_set = new dataset_type(m_point,1);
  m_tree = new KDTree(*m_set);
  m_tree->buildTree();
  NodeStats<KDTree> v;
  m_tree->visitRecursive(v, false);  // post-order visit
}

struct BoundingBoxDrawer 
{
  Plotter& m_pl;
  BoundingBoxDrawer(Plotter& pl) : m_pl(pl) {}
  void operator()(Tree* tree_node) {
    KDTree *node = static_cast<KDTree*>(tree_node);
    const BoundingBox& b = node->box();
    m_pl.drawRect(QRectF(m_pl.point(b.min()), m_pl.point(b.max())));
  }
};

void KDTreeBuild::draw(Plotter& pl)
{
  QPen pen(Qt::SolidLine);
  pen.setWidth(2);

  pen.setColor(Qt::black);
  common::drawVVec(m_point, pl, pen);

  if (m_tree) {
    pen.setColor(Qt::red);
    pen.setStyle(Qt::DashLine);
    pen.setWidth(1);
    pl.setPen(pen);
    
    BoundingBoxDrawer drawer(pl);
    m_tree->visitRecursive(drawer);
  }
}
